<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>10、Symbol——实例：模块的Singleton模式</title>
	</head>
	<body>
		<script type="text/javascript">
			//六、实例：模块的Singleton模式
			//1.Singleton模式指的是调用一个类，任何时候返回的都是同一个实例
			//对于Node来说，模块文件可以看成一个类。怎么保证每次执行这个模块文件，返回的都是同一个实例呢？
			//很容易想到，可以把实例放到顶层对象global
			//mod.js
			function A(){
				this.foo = 'hello';
			}
			if(!global._foo){
				global._foo = new A();
			}
			module.exports = global._foo;
			//然后，加载上面的mod.js
			const a = require('./mod.js');
			console.log(a.foo)
			//上面代码中，变量a任何时候加载的都是A的同一个实例。
			//但是，这里有一个问题，全局变量global._foo是可写的，任何文件都可以修改。
			const a = require('./mod.js')
			global._foo = 123;
			//上面的代码，会使得别的脚本加载mod.js都失真。
			
			//为了防止这种情况出现，我们就可以使用Symbol.
			//mod.js
			const FOO_KEY = Symbol.for('foo');
			function A(){
				this.foo = 'hello';
			}
			if(!global[FOO_KEY]){
				global[FOO_KEY] = new A();
			}
			module.exports = global[KOO_KEY];
			//上面代码中，可以保证global[FOO_KEY]不会被无意间覆盖，但还是可以被改写。
			const a = require('./mod.js');
			global[Symbol.for('foo')] = 123;
			//如果键名使用Symbol方法生成，那么外部将无法引用这个值，当然也就无法改写。
			
			//mod.js
			const FOO_KEY = Symbol('foo');
			//后面代码相同。。。
			//上面代码将导致其他脚本都无法引用FOO_KEY。但这样也有一个问题，就是如果多次执行这个脚本，每次得到的FOO_KEY都是不一样的。虽然Node会将脚本的执行结果缓存，一般情况下，不会多次执行同一个脚本，但是用户可以手动清除缓存，所以也不是完全可靠。
		</script>
	</body>
</html>
